
use axum::{
    extract::{ self, Query, State}, http::{header::{HeaderMap, SET_COOKIE}, StatusCode}, response::{IntoResponse, Json, Redirect, Response}, Form };

use axum::response::Html;
use axum::response::Result as AResult;

use serde::{Deserialize, Serialize, *};
use tracing_subscriber::field::debug;
use std::{collections::HashMap, sync::Arc};

use anyhow::{bail, Result};
use crate::*;
use chrono::prelude::*;
use common::{chat_with_glm_response, ChatParam};

type SharedHandle = Arc<Shared>;

pub async fn get_hello(State(shared): State<SharedHandle>, Query(q): Query<SearchParam>) ->  AResult<Response> {
   
    let s = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
    logging::log!("get_hello: {:?}", s);
    let r = shared.dataset.read().unwrap();
    let count = r.len();

    return Ok( Html(format!(
             r#"<html><head><h1 align=center><Warnning</h1></head><body><BR>
             <div><pre>
             axum server端构造的页面! 展示了如何和leptos共存的技术。
             leptos router 路由中，需要通过 rel=external设置，如：  
               href="/get_hello?query=abc" rel="external" 
             才可以跳出leptos的router。
             </pre></div>
             <BR>
             <div align=center><span style="color:red">GET不建议在axum中实现，请把界面构成都交给leptos处理，以保证一致风格！</span></div>
             <BR>
             <div> Input is : {:?}</div>
             <BR>
             <div> dataset count = {}</div>
             </body>
             </html>"#,
            q, count
         )).into_response() )      
 }
 pub async fn post_todo(State(shared): State<SharedHandle>, Form(q): Form<SearchParam>, )  -> AResult<Response> {  

    let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
    log::info!("{:?} insert into db, {:?}", q, &now);  

    let mut w = shared.dataset.write().unwrap();
    let mut t = Task { id: 0, name: q.query, timestamp: now , count:9};
    let count = w.len() as i32 + 1;
    t.id = count;
    (*w).push(t);
    drop(w);

    return Ok(Redirect::to("/").into_response());
}
/// GET， /axum/get_task
/// @return Vec<Task>
pub async fn api_get_task(State(shared): State<SharedHandle>, Query(q): Query<SearchParam>) ->  AResult<Response> {
        
    let tasks = db::read_all_tasks(&shared.dbpool, 20).await.unwrap();
    logging::log!("api_get_task: count = {}", tasks.len());
    return Ok(Json(tasks).into_response())      
 }

 /// POST， /axum/post_task
 /// @return direct to /auxm page
 pub async fn api_post_task(State(shared): State<SharedHandle>, Form(q): Form<Task>, )  -> AResult<Response> {  
    let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
    log::info!("{:?} insert into db, {:?}", q, &now);  
        
    let id = new_task(&shared.dbpool, &q.name, &now, q.count).await.unwrap();
    let next = format!("/axum?query={}", id);
    return Ok(Redirect::to(&next).into_response());
}
///////


// curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer abc" --data-raw '{"receive_id": "oc_89528a035b9fe947b60f593b3006d89a",  "msg_type": "text"}' http://192.168.2.100:3000/api/get_glm_chat

pub async fn get_glm_chat(State(shared): State<SharedHandle>, ) ->  AResult<Response> {        
    let chats =    read_last_chats(&shared.dbpool, 20).await.unwrap_or_default(); //.unwrap();
    logging::log!("api_get_task: count = {:?}", chats.len());
    return Ok(Json(chats).into_response())          
 }
 
 pub async fn new_chat_glm(State(shared): State<SharedHandle>,  Json(q): Json<ChatHistory>  )  -> AResult<Response> {  
    logging::log!("post json data = {:?}", q);
    if q.question.len() > 0 && q.response.len() > 0 {        
        let r = new_chat2db(&shared.dbpool, &q.question, &q.timestamp, &q.response ).await;
        if r.is_ok() {
            logging::log!("{:?}", r);
        }else { 
            logging::log!("new_chat2db error:{:?}", r);
        }
    }  
    return Ok("OK".into_response() )          
}

 // curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer abc" --data-raw '{"receive_id": "oc_89528a035b9fe947b60f593b3006d89a",  "msg_type": "text"}' http://192.168.2.100:3000/api/chat_glm

 pub async fn post_chat_glm(State(shared): State<SharedHandle>,  Query(q): Query<ChatParam>  )  -> AResult<Response> {  
    let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
     if q.question.len() > 0 {
        logging::log!("{:?}, {:?}", q, &now);
        let r = chat_with_glm_response(&q.question).await;
        if r.is_ok() {
            let resp = r.unwrap();
            let id_r = new_chat2db(&shared.dbpool, &q.question, &now, &resp).await;
            logging::log!("{:?}", id_r);
        }else { 
            logging::log!("chat_with_glm_response error:{:?}", r);
        }
     }  

     let chats =    read_last_chats(&shared.dbpool, 20).await.unwrap_or_default(); //.unwrap();
     logging::log!("read_last_chats: count = {:?}", chats.len());
     return Ok(Json(chats).into_response())          
}

 // curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer abc" http://192.168.2.100:3000/api/grep_search

pub async fn grep_search(State(shared): State<SharedHandle>, Query(q): Query<SearchParam>  )  -> AResult<Response> {  
    // let id = new_task(&shared.dbpool, &q.name, &now, q.count).await.unwrap();
    if q.query.is_empty(){
        let r = common::RegexResult::default();
        return Ok( Json(r).into_response());
    }

    let source_path = "/Users/lengshanshu/lengss/rust";      
    let files = common::collect_files(source_path, "rs,md,txt.js").unwrap_or_default();   
    let res = common::grep_file(&files, &q.query);
    if res.is_ok(){
        let res = res.unwrap();
        debug!("grep result:{}", res.len());
        return Ok(Json(res).into_response());            
    }else {
        let r = vec![ common::RegexResult::default()];       
        let mut re:HashMap<String, Vec<common::RegexResult>> = HashMap::new();
        re.insert("Error".to_owned(), r);
        return Ok(Json(re).into_response());
    }
}


// curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer abc" http://192.168.2.100:3000/api/get_api_hello
pub async fn get_api_hello(State(shared): State<SharedHandle>, ) ->  AResult<Response> {            
    logging::log!("get_api_hello");
    return Ok("OK".into_response())          
 }
